export function isObject(value: any): value is Record<string, any> {
  return value !== null && 
    typeof value === 'object' && 
    !Array.isArray(value) &&
    !(value instanceof Date) &&
    !(value instanceof RegExp) &&
    !(value instanceof Map) &&
    !(value instanceof Set) &&
    !(value instanceof WeakMap) &&
    !(value instanceof WeakSet) &&
    Object.prototype.toString.call(value) === '[object Object]';
}

type DeepPartial<T> = {
  [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> | null | undefined : T[P] | null | undefined;
} & {
  [K in string]?: any;
};

function deepMerge<T extends Record<string, any>>(
  target: T,
  source: DeepPartial<T>
): T {
  const result: any = { ...target };
  for (const key in source) {
    if (source.hasOwnProperty(key)) {
      const sourceValue = source[key];
      const targetValue = target[key];
      if (sourceValue !== undefined) {
        if (isObject(sourceValue) && isObject(targetValue)) {
          result[key] = deepMerge(targetValue, sourceValue as any);
        } else {
          result[key] = sourceValue;
        }
      }
    }
  }
  return result;
}

export { deepMerge };
